﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.IO;
using System.Reflection;

namespace WinBot
{
    class Configurator
    {
        public Configurator(string filePath) { _filePath = filePath; }
        public static string className = MethodBase.GetCurrentMethod().DeclaringType.Name;

        private string _filePath;
        public string FilePath
        {
            set { _filePath = value; }
            get { return _filePath; }
        }

        /// <summary>
        /// Set property in file.
        /// </summary>
        /// <param name="propertyName">Property name.</param>
        /// <param name="propertyValue">Property value.</param>
        /// <returns>Returns success.</returns>
        public bool SetProperty(string propertyName, string propertyValue)
        {
            CheckFile();
            string[] file = File.ReadAllLines(_filePath);

            StringBuilder newFile = new StringBuilder();
            string temp = String.Empty; bool found = false;
            foreach (string line in file)
            {
                temp = line;
                temp = TransformLine(temp);
                if (temp != String.Empty && temp.Contains('='))
                    if (temp.Substring(0, temp.IndexOf('=')) == propertyName)
                    {
                        found = true;
                        temp = temp.Substring(0, temp.IndexOf('=')) + " = " + propertyValue;
                        newFile.Append(temp + "\r\n");
                        continue;
                    }
                newFile.Append(line + "\r\n");
            }
            File.WriteAllText(_filePath, newFile.ToString(), Encoding.GetEncoding("UTF-8"));
            if (!found)
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": Property is not found in file.");
            else
                return true;
        }

        public string[] GetPropertyArray()
        {
            CheckFile();

            string[] propertyList = File.ReadAllLines(_filePath);
            for (int i = 0; i < propertyList.Length; i++)
                propertyList[i] = TransformLine(propertyList[i]);
            string[] newlist = propertyList.Where(str => str != "").ToArray();
            return newlist;
        }
        /// <summary>
        /// Get property name from string.
        /// </summary>
        /// <param name="property">String with property name and value.</param>
        /// <returns>Returns property name</returns>
        public static string GetPropertyNameFromString(string property)
        {
            property = TransformLine(property);
            if (!property.Contains('='))
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": Line does not contains equal('=') symbol.");
            return property.Substring(0, property.IndexOf('='));
        }
        /// <summary>
        /// Get property value from string.
        /// </summary>
        /// <param name="property">String with property name and value.</param>
        /// <returns>Returns property value.</returns>
        public static string GetPropertyValueFromString(string property)
        {
            property = TransformLine(property);
            if (!property.Contains('='))
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": Line does not contains equal('=') symbol.");
            return property.Substring(property.IndexOf('=') + 1, property.Length - property.IndexOf('=') - 1);
        }
        /// <summary>
        /// Get property value from conf file.
        /// </summary>
        /// <param name="propertyName">Property name.</param>
        /// <returns>Returns property value.</returns>
        public string GetProperty(string propertyName)
        {
            CheckFile();

            string line;
            using (StreamReader sreader = new StreamReader(_filePath))
            {
                while ((line = sreader.ReadLine()) != null)
                {
                    line = TransformLine(line);
                    if (line == String.Empty)
                        continue;
                    if (!line.Contains('='))
                        continue;
                    if (line.Substring(0, line.IndexOf('=')) == propertyName)
                    {
                        string propertyValue = line.Substring(line.IndexOf('=') + 1, line.Length - line.IndexOf('=') - 1);
                        return propertyValue;
                    }

                }
            }
            throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": Свойство не найдено.");
        }
        /// <summary>
        /// Creates new configuration file using array of strings.
        /// </summary>
        /// <param name="configList">Strings to write to file.</param>
        public void CreateConfigurationFile(string[] configList)
        {
            if (!File.Exists(_filePath))
                File.WriteAllLines(_filePath, configList);
            else
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": File not found (" + _filePath + ").");
        }

        private void CheckFile()
        {
            if (_filePath == String.Empty)
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": File path can't be empty string.");
            if ((_filePath != String.Empty) && (!File.Exists(_filePath)))
                throw new Exception(className + "." + MethodBase.GetCurrentMethod().Name + ": File not found (" + _filePath +").");
        }
        private static string TransformLine(string line)
        {
            if (line.Contains("="))
            {
                // Delete all spaces and tab symbols in the begining of line.
                for (int i = 0; i < line.Length; )
                    if (line[i] == ' ' || line[i] == '\t')
                        line = line.Remove(i, 1);
                    else break;
                // Delete all spaces and tab symbols before 'equal' symbol.
                for (int i = line.IndexOf('=') - 1; i > 0; i--)
                    if (line[i] == ' ' || line[i] == '\t')
                        line = line.Remove(i, 1);
                    else break;
                // Delete all spaces and tab symbols after 'equal' symbol.
                for (int i = line.IndexOf('=') + 1; i < line.Length; )
                    if (line[i] == ' ' || line[i] == '\t')
                        line = line.Remove(i, 1);
                    else break;
                // Delete all spaces and tab symbols in the end of line.
                for (int i = line.Length - 1; i > 0; i--)
                    if (line[i] == ' ' || line[i] == '\t')
                        line = line.Remove(i, 1);
                    else break;
                // Delete last space symbol.
                if (line[line.Length - 1] == ' ')
                    line = line.Remove(line.Length - 1, 1);
            }
            // Delete commentary line.
            if (line.Contains('#'))
            {
                line = line.Remove(line.IndexOf('#'));
            }
            return line;
        }
    }
}

